#ifndef __MUSIC_UI_HPP
#define __MUSIC_UI_HPP

#include "../lvgl/lvgl.h"
#include "CString.hpp"
#include "music_if.hpp"

class AbstractVolume;

struct music_t {
    CString  fileName;       // 文件名
    uint16_t duration;       // 时长
    uint16_t offset;         // 播放开始的偏移量
    uint32_t sample_rate;    // 采样率
    uint32_t bitPerSec;      // 每秒比特数(用于计算时长和进度条)
    uint16_t bitsPerSample;  // 每个采样点的比特数
    uint16_t numChannels;
};

#define music_ctl MusicCtl::getInstance()
class MusicCtl
{
private:
    uint16_t size_ = 0;
    uint16_t capacity_ = 0;
    music_t *musics_{};

    uint16_t playProcess = 0;   // 播放进度 单位 s
    uint16_t playingMusicIndex = 0;   // 正在播放的音乐的索引

    bool isRandom = false;      // 随机播放 或 顺序播放
    bool paused = false;        // 暂停播放

    void resize();

    MusicCtl() = default;

public:
    static MusicCtl *getInstance() { static MusicCtl instance; return &instance; };

    uint16_t size() const { return size_; }
    void loadSettings();

    // 添加音乐
    void addMusic(const music_t &music);

    uint16_t getPlayingMusicIndex() const { return playingMusicIndex; }
    music_t getMusic(uint16_t index) const { return musics_[index]; }
    music_t getPlayingMusic() const { return musics_[playingMusicIndex]; }

    // 播放进度
    void setPlayProcess(int16_t process);
    uint16_t getPlayProcess() const { return playProcess; }
    void addPlayProcess(int16_t process = 1) { setPlayProcess(playProcess + process); }

    // 暂停
    bool checkPaused() const { return paused; }
    void setPaused(bool paused) { this->paused = paused; }
    bool togglePaused() { paused = !paused; return paused; }

    // 随机播放 或 顺序播放
    bool checkRandom() const { return isRandom; }
    void setRandom(bool random) { isRandom = random; }
    bool toggleRandom() { isRandom = !isRandom; return isRandom; }

    // 播放下一首
    void playNext(int8_t flag = 0);
    void playPrev();
    void playOtherMusic(uint16_t index);

    // 按键操作
    void keyUp() { playNext(-1); }
    void keyDown() { playNext(1); }
    void keyLeft() { addPlayProcess(-5); }
    void keyRight() { addPlayProcess(5); }
};

#define music_ui MusicUI::getInstance()
class MusicUI
{
private:
    lv_obj_t *container;
    lv_obj_t *musicProcess;     // 音乐播放进度 "%02d:%02d"
    lv_obj_t *contro;           // 进度条
    lv_obj_t *musicFile;        // 正在播放的音乐的文件名
    lv_obj_t *listCon;          // 音乐列表容器

    MusicUI();

    // 加载音乐文件, 如果找不到文件则返回 false
    bool loadMusic();
    // 将音乐文件添加至列表
    void addMusicToList();
    // 单个音乐文件在列表中的 UI
    void addMusicItem(uint16_t index);
    // UI包含: 音乐进度条、播放按钮、下一首、上一首、暂停、随机播放、音量调节
    void addMusicController(lv_obj_t *bar);
    void setStyle(lv_obj_t *Btn);
    void adjustVolume(lv_obj_t *parent);
    void volumnBar(lv_obj_t *parent, const lv_image_dsc_t &img, AbstractVolume *vol);

    static void contro_cb(lv_event_t *e);
    static void timer_cb(lv_timer_t *e);

public:
    static MusicUI *getInstance() { static MusicUI instance; return &instance; };
    
    void freeMem();
    void build();

    // 设置播放进度
    void setPlayProcess();

    // 用于切换音乐后更新 UI
    void setUI();
    void resetUi();
};

#endif
